package repository

import (
	"context"
	"go-api/internal/config"

	"go-api/internal/model"

	"gorm.io/gorm"
)

type FindUserFilter struct {
	Email          string              `json:"email"`
	Phone          string              `json:"phone"`
	Name           string              `json:"name"`
	NickName       string              `json:"nickName"`
	AuditStatus    model.AuditStatus   `json:"auditStatus"`
	AuditStatusArr []model.AuditStatus `json:"auditStatusArr"`
	Status         int8                `json:"status"`
}

type UserRepository interface {
	Create(user *model.User) error
	Update(user *model.User) error
	Delete(id int64) error
	FindMany(filter FindUserFilter) (int64, []model.User, error)
	FindOnyByID(id int64) (bool, *model.User, error)
	FindUserByEPN(filter FindUserFilter) (int64, []model.User, error)
}

type userRepository struct {
	ctx context.Context
	db  *gorm.DB
}

func NewUserRepository(ctx context.Context) UserRepository {
	return &userRepository{
		ctx: ctx,
		db:  config.GetProvider(),
	}
}

// Create 创建用户
func (r *userRepository) Create(user *model.User) error {
	return r.db.Create(user).Error
}

// Update 更新用户
func (r *userRepository) Update(user *model.User) error {
	// todo  updates和save的区别
	return r.db.Updates(&user).Error
}

// Delete 删除用户
func (r *userRepository) Delete(id int64) error {
	return r.db.Delete(&model.User{}, id).Error
}

func (r *userRepository) FindOnyByID(id int64) (bool, *model.User, error) {
	tx := r.getBase()
	var res model.User
	err := tx.Where("id = ?", id).First(&res).Error
	if err != nil {
		if err == gorm.ErrRecordNotFound {
			return false, nil, nil
		}
		return false, nil, err
	}

	return true, &res, nil
}

// FindMany 查找用户
func (r *userRepository) FindMany(filter FindUserFilter) (int64, []model.User, error) {
	tx := r.getBase()
	count := int64(0)
	res := make([]model.User, 0)

	if filter.Email != "" {
		tx.Where("email = ?", filter.Email)
	}

	if filter.Phone != "" {
		tx.Where("phone = ?", filter.Phone)
	}

	if filter.Name != "" {
		tx.Where("name = ?", filter.Name)
	}

	if filter.Status != 0 {
		tx.Where("status = ?", filter.Status)
	}

	tx.Count(&count)
	result := tx.Find(&res)
	return count, res, result.Error
}

// FindUserByEPN  通过email phome name查询用户是否存在，or
func (r *userRepository) FindUserByEPN(filter FindUserFilter) (int64, []model.User, error) {
	tx := r.getBase()
	count := int64(0)
	res := make([]model.User, 0)

	if filter.Phone != "" {
		tx.Where("(email = ? or phone = ?)", filter.Email, filter.Phone)
	}

	if filter.AuditStatus != 0 {
		tx.Where("audit_status = ?", filter.AuditStatus)
	}

	if len(filter.AuditStatusArr) != 0 {
		tx.Where("audit_status in ?", filter.AuditStatusArr)
	}

	if filter.Status != 0 {
		tx.Where("status = ?", filter.Status)
	}

	tx.Count(&count)
	result := tx.Find(&res)
	return count, res, result.Error
}

func (r *userRepository) getBase() *gorm.DB {
	return r.db.Model(&model.User{})
}
